#ifndef ___fuse_create
#define ___fuse_create 1

#ifndef FUSE_USE_VERSION
#define FUSE_USE_VERSION 28
#endif

#include <stdio.h>
#include <stdlib.h>
#include "mtlib.c"
#include <fuse.h>
#include <fcntl.h>
#include <errno.h>
#include "logging.c"

struct datosCrearArch {
	char * path;
	char estado;
};

//Prototipos
int fuse_create(const char *, mode_t, struct fuse_file_info *);
void ___fuse_procesar_mensaje_create(unsigned char, mti_mensaje, struct datosCrearArch *);

//CREA UN ARCHIVO Y LUEGO LO ABRE EN EL MODO INDICADO
int fuse_create(const char * path, mode_t modo, struct fuse_file_info * ptr) {

	mti_mensaje datosMensaje;
	int resultado;
	short permisos;
	unsigned char centro_create = 0;
	unsigned int descriptorConexion;
	struct datosCrearArch datos;

		datos.estado = 0;
		datos.path = path;

		if ((modo &32768) == S_IFREG) {
			permisos = (modo) &0511; //obtengo con chmod los ultimos 9 bits de permisos

		} else
			return -EISDIR;

		  while (!centro_create)
			  centro_create = mtf_obtener_descriptor(1024);

		  descriptorConexion = mtf_conectar(centro_create, MTP_INTERNO, centro_fat);

		  if (descriptorConexion == 0) {
		    mtf_liberar_descriptor(centro_create);
		    return -EAGAIN;
		  }

		  resultado = mtf_enviar_mensaje(centro_create, descriptorConexion, MTE_CREAR_ARCHIVO, (char *) datos.path, (int) permisos);

		  if (resultado == 0) {
		    mtf_desconectar(centro_create, descriptorConexion);
		    mtf_liberar_descriptor(centro_create);
		    return -EAGAIN;
		  }

		  while (!datos.estado) {

		    if (!mtf_recibir_mensajes(centro_create)) continue;

		    datosMensaje = mtf_siguiente_mensaje(centro_create);
		    ___fuse_procesar_mensaje_create(centro_create, datosMensaje, &datos);
		    mtf_descartar_mensaje(centro_create, datosMensaje.codigo);

		  }

		  mtf_desconectar(centro_create, descriptorConexion); //desconecto la conexion del centro de mensajes
		  mtf_liberar_descriptor(centro_create); //libero centro de mensajes con sus datos y conexiones

		  switch (datos.estado) {

		    case 1:
                return -EEXIST; //ya existe el archivo
		    case 2:
                return -ENOENT; //path no existe
            case 3:
                return -EACCES; //disco lleno
		    default:
		    	return EXIT_SUCCESS;
		  }

}

void ___fuse_procesar_mensaje_create(unsigned char centro_create, mti_mensaje datosMensaje, struct datosCrearArch * datosCrear) {

	if (datosMensaje.categoria != MTA_MENSAJE) return;

	  switch (datosMensaje.tipo) {

	    case MTE_NULL:

	      mtf_enviar_mensaje(centro_create, datosMensaje.remitente, MTR_NULL);

	    break;

	    case MTR_NULL: case MTQ_MENSAJE_NO_VALIDO:

	    break;

		//MENSAJES PARA CREAR UN ARCHIVO
		case MTR_ARCHIVO_CREADO:
		{
			char * nombreArchivo = NULL;

				mtf_obtener_datos(centro_create, datosMensaje.codigo,(char **) &nombreArchivo);
				
                log_registrar(descArch, "FUSE", LOG_INFO, "Pudo crear el archivo %s \n", nombreArchivo);
				free(nombreArchivo);
		}
		break;

		case MTR_NO_CREO_ARCHIVO:
		{

			char * nombreArchivo = NULL;
			char motivo;

				mtf_obtener_datos(centro_create, datosMensaje.codigo, (char **) &nombreArchivo,(char *) &motivo);

				datosCrear -> estado = motivo;
				log_registrar(descArch, "FUSE", LOG_WARN, "No se pudo crear el archivo %s \n", nombreArchivo);
				free(nombreArchivo);
			
		}
		break;

		default:

		      mtf_enviar_mensaje(centro_create, datosMensaje.remitente, MTQ_MENSAJE_NO_VALIDO);

		break;

	  }
}

#endif
